//
//  MPShadowView.m
//  MissPaparazzi
//
//  Created by Alexey Aleshkov on 23.09.12.
//  Copyright (c) 2012 DzeTech. All rights reserved.
//


#import "MPShadowView.h"


@implementation MPShadowView

@synthesize shadowInsets = _shadowInsets;
@synthesize shadowRadius = _shadowRadius;
@synthesize shadowBlur = _shadowBlur;
@synthesize fillColor = _fillColor;

#pragma mark -
#pragma mark Common Init / Dealloc

- (void)initialization
{
	CGFloat kInset = 4;
	_shadowInsets = UIEdgeInsetsMake(kInset, kInset, kInset, kInset);
	_shadowRadius = kInset * 3 / 2;
	_shadowBlur = _shadowRadius * 4 / 3;
}

- (void)deinitialization
{
	[_fillColor release];
}

#pragma mark -
#pragma mark Init / Dealloc

- (id)initWithFrame:(CGRect)frame
{
	self = [super initWithFrame:frame];
	if (!self) {
		return nil;
	}
	
	[self initialization];
	
	return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
	self = [super initWithCoder:aDecoder];
	if (!self) {
		return nil;
	}
	
	[self initialization];
	
	return self;
}

- (void)dealloc
{
	[self deinitialization];
	[super dealloc];
}

#pragma mark -
#pragma mark Overrides

- (void)drawRect:(CGRect)rect
{
	CGContextRef context = UIGraphicsGetCurrentContext();
	
	CGRect bounds = UIEdgeInsetsInsetRect(self.bounds, _shadowInsets);
	CGFloat radius = _shadowRadius;
	
	// Create the "visible" path, which will be the shape that gets the inner shadow
	// In this case it's just a rounded rect, but could be as complex as your want
	CGMutablePathRef visiblePath = CGPathCreateMutable();
	CGRect innerRect = CGRectInset(bounds, radius, radius);
	CGPathMoveToPoint(visiblePath, NULL, innerRect.origin.x, bounds.origin.y);
	CGPathAddLineToPoint(visiblePath, NULL, innerRect.origin.x + innerRect.size.width, bounds.origin.y);
	CGPathAddArcToPoint(visiblePath, NULL, bounds.origin.x + bounds.size.width, bounds.origin.y, bounds.origin.x + bounds.size.width, innerRect.origin.y, radius);
	CGPathAddLineToPoint(visiblePath, NULL, bounds.origin.x + bounds.size.width, innerRect.origin.y + innerRect.size.height);
	CGPathAddArcToPoint(visiblePath, NULL,  bounds.origin.x + bounds.size.width, bounds.origin.y + bounds.size.height, innerRect.origin.x + innerRect.size.width, bounds.origin.y + bounds.size.height, radius);
	CGPathAddLineToPoint(visiblePath, NULL, innerRect.origin.x, bounds.origin.y + bounds.size.height);
	CGPathAddArcToPoint(visiblePath, NULL,  bounds.origin.x, bounds.origin.y + bounds.size.height, bounds.origin.x, innerRect.origin.y + innerRect.size.height, radius);
	CGPathAddLineToPoint(visiblePath, NULL, bounds.origin.x, innerRect.origin.y);
	CGPathAddArcToPoint(visiblePath, NULL,  bounds.origin.x, bounds.origin.y, innerRect.origin.x, bounds.origin.y, radius);
	CGPathCloseSubpath(visiblePath);
	
	
	// Fill this path
	if (_fillColor) {
		[_fillColor setFill];
		CGContextAddPath(context, visiblePath);
		CGContextFillPath(context);
	}
	
	// Now create a larger rectangle, which we're going to subtract the visible path from
	// and apply a shadow
	CGMutablePathRef path = CGPathCreateMutable();
	//(when drawing the shadow for a path whichs bounding box is not known pass "CGPathGetPathBoundingBox(visiblePath)" instead of "bounds" in the following line:)
	//-42 cuould just be any offset > 0
	CGPathAddRect(path, NULL, CGRectInset(bounds, -42, -42));
	// Add the visible path (so that it gets subtracted for the shadow)
	CGPathAddPath(path, NULL, visiblePath);
	CGPathCloseSubpath(path);
	
	
	// Add the visible paths as the clipping path to the context
	CGContextAddPath(context, visiblePath);
	CGContextClip(context);
	
	
	// Now setup the shadow properties on the context
	UIColor *shadowColor;
	shadowColor = [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0f];
	//CGContextSaveGState(context);
	CGContextSetShadowWithColor(context, CGSizeMake(0.0f, 0.0f), _shadowBlur, [shadowColor CGColor]);
	// Now fill the rectangle, so the shadow gets drawn
	[shadowColor setFill];

	//CGContextSaveGState(context);
	CGContextAddPath(context, path);
	CGContextEOFillPath(context);
	
	// Release the paths
	CGPathRelease(path);    
	CGPathRelease(visiblePath);
}

- (void)setFrame:(CGRect)frame
{
	[super setFrame:frame];
	[self setNeedsDisplay];
}

#pragma mark -
#pragma mark Properties

- (void)setShadowInsets:(UIEdgeInsets)shadowInsets
{
	_shadowInsets = shadowInsets;
	[self setNeedsDisplay];
}

- (void)setShadowRadius:(CGFloat)shadowRadius
{
	_shadowRadius = MAX(0, shadowRadius);
	[self setNeedsDisplay];
}

- (void)setShadowBlur:(CGFloat)shadowBlur
{
	_shadowBlur = MAX(0, shadowBlur);
	[self setNeedsDisplay];
}

- (void)setFillColor:(UIColor *)fillColor
{
	id oldValue = _fillColor;
	_fillColor = [fillColor retain];
	[oldValue release];
	[self setNeedsDisplay];
}

@end
